home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * This is a simple program to demonstrate
- * extracting information from the Macintosh
- * parameter RAM and displaying the current
- * latitude, longitude, and time-zone offset.
- * Note that the format and manner of storage
- * of this data have not been published by
- * Apple.
- *
- * This program is copyright © 1988, 1989
- * by MacTutor magazine. You may incorpor-
- * ate portions of this program in your
- * applications without restriction.
- *
- * Compile using Think C, V3.0.
- *
- * Written by Martin Minow and Mike Carleton
- */
-
- #include <stdio.h>
-
- /*
- * Define the "Read parameter ram" trap and
- * the offset in the parameter ram where the
- * map is stored. This information doesn't
- * seem to be written down anywhere.
- */
- #define _ReadXPRam 0xA051
- #define Map_Offset 0xE4 /* Ram offset */
-
- /*
- * This structure defines the location
- * currently set by the Map Cdev.
- *
- * Latitude and longitude are long integers
- * specifying the fraction of the circle:
- * 1 degree East == 0x000308B9
- * 1 degree West == 0xFFFCF747
- * All values are possible for longitude,
- * while latitude is constrained to ± 90°.
- *
- * Only the low-order three bytes of timezone
- * are used. The value is the number of
- * seconds offset from UTC, East is positive,
- * West negative.
- */
- #ifdef Use_Script_Manager
- #include <ScriptMgr.h>
-
- typedef struct {
- Fract latitude;
- Fract longitude;
- union {
- char dlsDelta;
- long gmtDelta;
- } gmtFlags;
- } MachineLocation;
-
- MachineLocation info;
- pascal void ReadLocation(MachineLocation *);
- #else
- typedef struct {
- long latitude;
- long longitude;
- long timezone;
- } MapDatum;
-
- MapDatum info;
- #endif
-
- void main(void);
- void dms(long, char *, char *);
- void hms(long, char *);
- OSErr read_param_ram(void *, int, int);
-
- void printf(char *, ...);
- int fgetc(FILE *);
-
- void
- main()
- {
- OSErr status;
-
- /*
- * This is a test for divide rounding.
- * It should yield 180°00'00" W.
- */
- dms(0x80000000L, "Test", "EW");
- /*
- * Loop through here until the user
- * types 'q' -- this lets you run the Map
- * Cdev at the same time to see how
- * location and timezone changes affect
- * the data.
- */
- do {
-
- #ifdef Use_Script_Manager
- ReadLocation(&info);
- dms(info.latitude, "Latitude", "NS");
- dms(info.longitude,
- "Longitude", "EW");
- hms(info.gmtFlags.gmtDelta, "Zone");
- #else
- status = read_param_ram(
- &info,
- Map_Offset,
- sizeof (MapDatum)
- );
- if (status != noErr)
- printf("Error %d\n", status);
- dms(info.latitude, "Latitude", "NS");
- dms(info.longitude,
- "Longitude", "EW");
- hms(info.timezone, "Zone");
- #endif
- } while (getchar() != 'q');
- }
-
- /*
- * Convert to degrees/minutes/seconds.
- */
- void
- dms(raw_value, what, zone)
- long raw_value;
- char *what;
- char *zone;
- {
- register long value;
- register long degree, minute, second;
- int west;
-
- static long one_degree =
- (0x80000000L / 180L);
- static long one_minute =
- (0x80000000L / (180L * 60L));
- static long one_second =
- (0x80000000L / (180L * 60L * 60L));
-
- value = raw_value;
- degree = value / one_degree;
- value -= (degree * one_degree);
- minute = value / one_minute;
- value -= (minute * one_minute);
- second = value / one_second;
- if ((west = (raw_value < 0))) {
- degree = (-degree);
- minute = (-minute);
- second = (-second);
- }
- printf(
- "%08lx: %3ld°%02ld'%02ld\" %c %s\n",
- raw_value, degree, minute, second,
- zone[west], what
- );
- }
-
- /*
- * Convert time to hours:minutes:seconds.
- */
- void
- hms(timezone, what)
- long timezone;
- char *what;
- {
- register long value;
- register long hour, minute, second;
- int west;
-
- static long one_hour = (60L * 60L);
- static long one_minute = (60L);
-
- if (timezone & 0xFF000000) {
- printf("timezone high byte %08lx\n",
- timezone);
- timezone &= 0x00FFFFFF;
- }
- /*
- * Propogate the sign bit from bit 23
- * to bit 31 if West of UTC.
- */
- if ((timezone & 0x00800000) != 0)
- timezone |= 0xFF000000;
- value = timezone;
- hour = value / one_hour;
- value -= (hour * one_hour);
- minute = value / one_minute;
- value -= (minute * one_minute);
- second = value;
- if ((west = (timezone < 0))) {
- hour = (-hour);
- minute = (-minute);
- second = (-second);
- }
- printf(
- "%08lx: %3ld.%02ld.%02ld %c %s\n",
- timezone, hour, minute, second,
- "EW"[west], what
- );
- }
-
- /*
- * Read data from the clock parameter ram.
- * The start parameter specifies the offset
- * within the parameter ram where the read
- * is to start. The count parameter specifies
- * the number of bytes to read.
- */
- OSErr
- read_param_ram(address, start, count)
- void *address; /* Result loc */
- int start; /* Ram start */
- int count; /* Read size */
- {
- /*
- * Put the count into the high word of
- * D0, the pRRAM start address into the
- * low word of D0, the Macintosh memory
- * address in A0, and trap to ROM.
- * _ReadXPRam returns noErr on success
- * and prInitErr on failure.
- */
- asm {
- move.w count,D0
- swap D0
- move.w start,D0
- movea.l address,A0
- dc.w _ReadXPRam
- return
- }
- }
-
-